package com.xinyue.game.server.logic.player;

import com.xinyue.game.server.common.EnumGameError;
import com.xinyue.game.server.dao.entity.PlayerEntity;
import com.xinyue.game.server.logic.messages.EnterGameRequest;
import com.xinyue.game.server.logic.messages.EnterGameResponse;
import com.xinyue.game.server.logic.player.event.LoginOutEvent;
import com.xinyue.server.framework.common.GameAsyncTaskService;
import com.xinyue.server.framework.handlermapping.GameChannelContext;
import com.xinyue.server.framework.handlermapping.GameHandlerComponent;
import com.xinyue.server.framework.handlermapping.GameMapping;
import com.xinyue.server.framework.handlermapping.GameServerCacheService;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;


/**
 * 角色模块相关处理
 */
@GameHandlerComponent
public class PlayerHandler {
    private static final Logger logger = LoggerFactory.getLogger(PlayerHandler.class);
    @Autowired
    private PlayerService playerService;

    @Autowired
    private UserService userService;
    @Autowired
    private GameAsyncTaskService gameAsyncTaskService;
    @Autowired
    private GameServerCacheService gameChannelService;
    @Autowired
    private ApplicationContext context;
    @Autowired
    private PlayerCacheService playerCacheService;

    private void bindChannel(ChannelHandlerContext ctx, String playerId) {
        GamePlayerCacheModel gamePlayerCacheModel = new GamePlayerCacheModel(ctx, playerId);
        gameChannelService.bindChannel(gamePlayerCacheModel);
        ctx.channel().closeFuture().addListener(future -> {
            // 当用于离线时，发送离事事件
            LoginOutEvent loginOutEvent = new LoginOutEvent(this, playerId);
            context.publishEvent(loginOutEvent);
        });
    }

    /**
     * 进入游戏
     *
     * @param ctx
     * @param request
     */
    @GameMapping(EnterGameRequest.class)
    public void enterGame(GameChannelContext ctx, EnterGameRequest request) {
        String userId = request.getUserId();
        userService.checkUserId(userId);
        userService.checkToken(userId, request.getToken());
        logger.debug("用户认证成功，userId: {},token:{}", userId, request.getToken());
        this.bindChannel(ctx.getNettyCtx(), request.getPlayerId());
        gameAsyncTaskService.execute(request.getPlayerId(), "获取玩家信息", () -> {
            PlayerEntity playerEntity = playerCacheService.getPlayerOrLoading(request.getPlayerId());
            if (playerEntity == null) {
                ctx.writeAndFlush(EnumGameError.ROLE_NOT_EXIST);
            } else {
                EnterGameResponse response = new EnterGameResponse();
                response.setRole(playerEntity);
                ctx.writeAndFlush(response);
            }
        });
    }

}
